package servlets;

import java.io.IOException;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import config.ConfigManager;
import searcher.DocumentSearcher;
import domain.Document;
import exception.InvalidConfigException;

/**
 * Servlet implementation class FindDocumentsServlet
 */
public class FindDocumentsServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	private static final String FIRST_PAGE_KEY = "first";
	private static final String LAST_PAGE_KEY = "last";
	private static final String NEXT_PAGE_KEY = "+";
	private static final String PREVIOUS_PAGE_KEY = "-";

	private static int RESULTS_PER_PAGE;
	static {
		try {
			RESULTS_PER_PAGE = ConfigManager.getIntConfig("results_per_page");
		} catch (InvalidConfigException e) {
			e.printStackTrace();
			RESULTS_PER_PAGE = 16;
		}
	}
	private static int CURRENT_PAGE;

	private List<Document> lastSearch; 

	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String page = request.getParameter("page");
		String query = request.getParameter("search");
		int indexFrom = 0;
		int indexTo = 0;
		if (page != null && !page.equals("")) {
			if (FIRST_PAGE_KEY.equals(page)) {
				CURRENT_PAGE = 1;
				indexFrom = 0;
				indexTo = Math.min(lastSearch.size(), RESULTS_PER_PAGE);
			}
			else if (LAST_PAGE_KEY.equals(page)) {
				int pagesCount = pagesCount();
				CURRENT_PAGE = pagesCount;
				indexFrom = Math.min(lastSearch.size(), (RESULTS_PER_PAGE * pagesCount) - RESULTS_PER_PAGE);
				indexTo = lastSearch.size();
			}
			else if (NEXT_PAGE_KEY.equals(page)) {
				int nextPage = nextPage();
				CURRENT_PAGE = nextPage;
				indexFrom = Math.min(lastSearch.size(), (RESULTS_PER_PAGE * nextPage) - RESULTS_PER_PAGE);
				indexTo = Math.min(lastSearch.size(), RESULTS_PER_PAGE * nextPage);
			}
			else if (PREVIOUS_PAGE_KEY.equals(page)) {
				int previousPage = previousPage();
				CURRENT_PAGE = previousPage;
				indexFrom = Math.min(lastSearch.size(), (RESULTS_PER_PAGE * previousPage) - RESULTS_PER_PAGE);
				indexTo = Math.min(lastSearch.size(), RESULTS_PER_PAGE * previousPage);
			}
			else { // numero de pagina
				int pageNumber = Integer.parseInt(page);
				pageNumber = pageNumber <= pagesCount() ? pageNumber : pagesCount();
				CURRENT_PAGE = pageNumber;
				indexFrom = Math.min(lastSearch.size(), (RESULTS_PER_PAGE * pageNumber) - RESULTS_PER_PAGE);
				indexTo = Math.min(lastSearch.size(), RESULTS_PER_PAGE * pageNumber);
			}
		}
		else {
			if (query != null) {
				query = query.trim();
				// ejecutar la busqueda
				DocumentSearcher searcher = new DocumentSearcher();
				lastSearch = searcher.search(query);
				indexFrom = 0;
				indexTo = Math.min(lastSearch.size(), RESULTS_PER_PAGE);
				CURRENT_PAGE = 1;
			}
			else {
				return;
			}
		}
		
		request.setAttribute("documents", lastSearch.subList(indexFrom, indexTo));
		request.setAttribute("search", query);
		request.setAttribute("pagesCount", pagesCount());
		request.setAttribute("currentPage", CURRENT_PAGE);
		response.setContentType("text/html; charset=UTF-8");
		RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/index.jsp");
		if (dispatcher != null)
			dispatcher.include(request, response);
	}
	
	private int pagesCount() {
		int ret = 0;
		if (lastSearch.size() <= RESULTS_PER_PAGE) {
			ret = 1;
		}
		else if (lastSearch.size() % RESULTS_PER_PAGE == 0) {
			ret = lastSearch.size() / RESULTS_PER_PAGE;
		}
		else if (lastSearch.size() % RESULTS_PER_PAGE != 0) {
			ret =  (lastSearch.size() / RESULTS_PER_PAGE) + 1;
		}
		return ret;
	}

	private int nextPage() {
		int ret = 0;
		if (CURRENT_PAGE == pagesCount()) {
			ret = CURRENT_PAGE;
		}
		else if (RESULTS_PER_PAGE * CURRENT_PAGE < lastSearch.size()) {
			ret = CURRENT_PAGE + 1;
		}
		else if (RESULTS_PER_PAGE * CURRENT_PAGE == lastSearch.size()) {
			ret = CURRENT_PAGE;
		}
		else if (lastSearch.size() % RESULTS_PER_PAGE == 0) {
			ret = CURRENT_PAGE + 1;
		}
		return ret;
	}

	private int previousPage() {
		int ret = 0;
		if (CURRENT_PAGE == 1) {
			ret = CURRENT_PAGE;
		}
		else {
			ret = CURRENT_PAGE - 1;
		}
		return ret;
	}
}
